package com.dmap.knowledge.service.impl;

import com.dmap.knowledge.bo.cloum.AppColumnKey;
import com.dmap.knowledge.cache.HotArticleCacheDao;
import com.dmap.knowledge.cache.TodayArticleCacheDao;
import com.dmap.knowledge.cache.po.HotArticleCachePo;
import com.dmap.knowledge.cache.po.TodayArticleCachePo;
import com.dmap.knowledge.controller.api.param.ArticleAppParam;
import com.dmap.knowledge.controller.api.param.ArticleMockParam;
import com.dmap.knowledge.controller.api.param.ArticleTagParam;
import com.dmap.knowledge.dao.ArticleMapper;
import com.dmap.knowledge.po.*;
import com.dmap.knowledge.service.*;
import com.dmap.knowledge.vo.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author zmh
 * @date 18-7-18 下午7:09
 */
@Service
public class ArticleExtensionServiceImpl implements ArticleExtensionService {
    private static final Logger logger = Logger.getLogger(ArticleExtensionServiceImpl.class);
    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleTagService articleTagService;
    @Resource
    private ArticleService articleService;
    @Resource
    private ArticleColumnService articleColumnService;
    @Resource
    private ArticleColumnAppService articleColumnAppService;
    @Resource
    private HotArticleCacheDao hotArticleCacheDao;
    @Resource
    private TodayArticleCacheDao todayArticleCacheDao;

    @Override
    public List<ArticleLinkVo> selectArticleLinkList(String companyNumber, String appNumber, String lang, String columnId, int database, int pageIndex, int pageSize) {
        List<Article> articleList;
        ArticleExample articleExample = new ArticleExample();
        articleExample.setLimitStart((pageIndex - 1) * pageSize);
        articleExample.setLimitEnd(pageSize);
        articleExample.setOrderByClause("recommend_index asc,browse_number desc,publish_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        if (companyNumber != null) {
            articleCriteria.andCompanyNumberEqualTo(companyNumber);
        }
        if (lang != null) {
            articleCriteria.andLangEqualTo(lang);
        }
        if (columnId != null) {
            articleCriteria.andColumnIdEqualTo(Long.parseLong(columnId));
        }
        if (appNumber != null) {
            articleCriteria.andAppNumberEqualTo(appNumber);
        }
        List<ArticleLinkVo> articleVoList = new ArrayList<>();
        articleList = articleMapper.selectByExample(articleExample);
        ArticleLinksVo articleLinksVo = new ArticleLinksVo();
        articleList.forEach(article -> {
            ArticleLinkVo articleLinkVo = new ArticleLinkVo(article);
            articleVoList.add(articleLinkVo);
        });
        articleLinksVo.setCount(countArticleLinkList(companyNumber, appNumber, lang, columnId, database));
        articleLinksVo.setArticleLinksVoList(articleVoList);
        return articleVoList;
    }

    @Override
    public int countArticleLinkList(String companyNumber, String appNumber, String lang, String columnId, int database) {
        ArticleExample articleExample = new ArticleExample();
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        if (companyNumber != null) {
            articleCriteria.andCompanyNumberEqualTo(companyNumber);
        }
        if (lang != null) {

            articleCriteria.andLangEqualTo(lang);
        }
        if (columnId != null) {
            articleCriteria.andColumnIdEqualTo(Long.parseLong(columnId));
        }
        if (appNumber != null) {
            articleCriteria.andAppNumberEqualTo(appNumber);
        }
        return articleMapper.countByExample(articleExample);
    }

    @Override
    public int updateArticleNumber(long articleId) {
        Article article = articleService.selectByArticleId(articleId);
        if (article == null) {
            return 0;
        }
        article.setBrowseNumber(article.getBrowseNumber() + 1);
        return articleMapper.updateByPrimaryKeySelective(article);
    }

    @Override
    public List<ArticleDetailVo> selectByArticleColumnId(String lang, String projectId, long columnId, int pageIndex, int pageSize) {
        List<ArticleDetailVo> articleDetailVoList = new ArrayList<>(pageSize);
        long currentTime = System.currentTimeMillis() / 1000;
        ArticleExample articleExample = new ArticleExample();
        articleExample.setLimitStart((pageIndex - 1) * pageSize);
        articleExample.setLimitEnd(pageSize);
        //按照最近时间发布活动文章
        articleExample.setOrderByClause("publish_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        //发布时间小于当前时间
        articleCriteria.andPublishTimeLessThanOrEqualTo(currentTime);
        //截止时间大于当前时间
        articleCriteria.andUsefulTimeGreaterThanOrEqualTo(currentTime);
        //发布出去 ：是否发布：1 发布，2 ,未发布
        articleCriteria.andPublishEqualTo(1);
        articleCriteria.andAppNumberEqualTo(projectId);
        articleCriteria.andColumnIdEqualTo(columnId);
        articleCriteria.andLangEqualTo(lang);
        List<Article> articleList = articleMapper.selectByExample(articleExample);
        for (Article article : articleList) {
            ArticleDetailVo articleDetailVo = new ArticleDetailVo(article);
            articleDetailVo.setTags(articleService.getArticleTagNames(article.getId()));
            articleDetailVoList.add(articleDetailVo);
        }
        return articleDetailVoList;
    }

    @Override
    public List<ArticleDetailVo> selectByArticleColumnIdFirst(String lang, String projectId, long columnId, int pageIndex, int pageSize, List<Long> exceptIdList) {
        /**
         * 首页推荐，每个栏目只推荐一个
         */
        List<Article> articleList;
        List<ArticleDetailVo> articleDetailVos = new ArrayList<>();
        ArticleExample articleExample = new ArticleExample();
        /**
         * 按照栏目最近publish的时间
         */
        //按照最近时间发布活动文章
        articleExample.setOrderByClause("publish_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        //发布时间小于当前时间
        articleCriteria.andPublishTimeLessThanOrEqualTo(System.currentTimeMillis() / 1000);
        //截止时间大于当前时间
        articleCriteria.andUsefulTimeGreaterThanOrEqualTo(System.currentTimeMillis() / 1000);
        //排除今日推荐的id
        if (CollectionUtils.isNotEmpty(exceptIdList)) {
            articleCriteria.andIdNotIn(exceptIdList);
        }
        //发布出去 ：是否发布：1 发布，2 ,未发布
        articleCriteria.andPublishEqualTo(1);
        articleCriteria.andAppNumberEqualTo(projectId);
        articleCriteria.andColumnIdEqualTo(columnId);
        articleCriteria.andLangEqualTo(lang);
        //没有启用的不能进行启用
        List<ArticleColumn> articleColumnList = articleColumnService.selectArticleColumnNotOn();
        List<Long> articleColumnIds = new ArrayList<>();
        articleColumnList.forEach(articleColumn -> {
            articleColumnIds.add(articleColumn.getId());
        });
        articleCriteria.andColumnIdNotIn(articleColumnIds);
        articleList = articleMapper.selectByExample(articleExample);
        int i = 0;
        for (Article article : articleList) {
            List<ArticleColumnApp> articleColumnAppList = articleColumnAppService.selectColumnAppNotOn(article.getLang(), article.getAppNumber(), article.getColumnId());
            if (!articleColumnAppList.isEmpty()) {
                continue;
            }
            ArticleDetailVo articleDetailVo = new ArticleDetailVo(article);
            articleDetailVo.setTags(articleService.getArticleTagNames(article.getId()));
            articleDetailVos.add(articleDetailVo);
            i++;
            if (i > 1) {
                break;
            }
        }
        return articleDetailVos;
    }

    @Override
    public List<ArticleDetailVo> selectHotArticle(String lang, String projectId) {
        List<HotArticleCachePo> hotArticleCachePoList = hotArticleCacheDao.selectColumnArticle(lang, projectId);
        List<ArticleDetailVo> articleDetailVos = new ArrayList<>();
        //如果为空就增加缓存
        if (CollectionUtils.isEmpty(hotArticleCachePoList)) {
            hotArticleCachePoList = updateHotArticleCachePo(lang,projectId);
        }
        //暂存hotArticle
        List<HotArticleCachePo> hotArticleCachePoTemp = new ArrayList<>();
        //如果是size为1  产生随机数
        if (hotArticleCachePoList.size() == 1) {
            hotArticleCachePoTemp.add(hotArticleCachePoList.get(0));
        } else if(hotArticleCachePoList.size() > 1){
            List<Integer> arr = articleService.createRandom(hotArticleCachePoList.size() - 1);
            int num1 = 0;
            int num2 = 0;
            if (CollectionUtils.isNotEmpty(arr)) {
                num1 = arr.get(0);
                num2 = arr.get(1);
            }
            hotArticleCachePoTemp.add(hotArticleCachePoList.get(num1));
            hotArticleCachePoTemp.add(hotArticleCachePoList.get(num2));
        }
        hotArticleCachePoTemp.forEach(hotArticleCachePo -> {
            ArticleDetailVo articleDetailVo = new ArticleDetailVo(hotArticleCachePo);
            articleDetailVos.add(articleDetailVo);
        });
        return articleDetailVos;

    }

    /**
     * 今日推荐
     * 从所有栏目，选取录入时间最近的三篇文章发布
     */
    @Override
    public List<ArticleDetailVo> selectTodayArticle(String lang, String projectId) {
        List<TodayArticleCachePo> todayArticleCachePoList = todayArticleCacheDao.selectTodayArticle(lang,projectId);
        if(CollectionUtils.isEmpty(todayArticleCachePoList)){
            todayArticleCachePoList = updateTodayArticleCachePo(lang,projectId);
        }
        List<ArticleDetailVo> articleDetailVoList = new ArrayList<>();
        todayArticleCachePoList.forEach(todayArticleCachePo -> {articleDetailVoList.add(new ArticleDetailVo(todayArticleCachePo));});
        return articleDetailVoList;
    }


    @Override
    public List<ArticleDetailVo> selectArticleByColumnId(String lang, String projectId, long columnId) {
        List<Article> articleList;
        List<ArticleDetailVo> articleDetailVos = new ArrayList<>();
        ArticleExample articleExample = new ArticleExample();
        articleExample.setOrderByClause("recommend_index asc,public_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        articleCriteria.andAppNumberEqualTo(projectId);
        articleCriteria.andColumnIdEqualTo(columnId);
        articleCriteria.andLangEqualTo(lang);
        articleList = articleMapper.selectByExample(articleExample);
        List<String> articleTagNames = new ArrayList<>();
        articleList.forEach(article -> {
            articleTagService.selectByArticleId(article.getId()).forEach(articleTag -> articleTagNames.add(articleTag.getTagName()));
            ArticleDetailVo articleDetailVo = new ArticleDetailVo(article);
            articleDetailVo.setTags(articleTagNames);
            articleDetailVos.add(articleDetailVo);
        });
        return articleDetailVos;
    }

    @Override
    public int countArticleByColumn(String appNumber, long columnId) {
        ArticleExample articleExample = new ArticleExample();
        ArticleExample.Criteria criteria = articleExample.createCriteria();
        criteria.andColumnIdEqualTo(columnId);
        //按照appNumber进行筛选
        if (appNumber != null) {
            criteria.andAppNumberEqualTo(appNumber);
        }
        return articleMapper.countByExample(articleExample);
    }

    @Override
    public List<HotArticleCachePo> updateHotArticleCachePo(String lang, String projectId) {
        List<HotArticleCachePo> hotArticleCachePoList = new ArrayList<>();
        List<Article> articleList;
        //获取7天之后当前时间
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, -7);
        Date d = c.getTime();
        long ts = d.getTime();
        long currentTime = System.currentTimeMillis() / 1000;
        ArticleExample articleExample = new ArticleExample();
        //按照阅读量排序
        articleExample.setOrderByClause("browse_number desc,publish_time desc");
        //六条数据
        //计数器  0-6   2个翻页
        articleExample.setLimitStart(0);
        articleExample.setLimitEnd(8);
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        //7日内阅读数最高的2/4/6篇文章
        articleCriteria.andPublishTimeGreaterThanOrEqualTo(ts / 1000);
        //发布时间小于当前时间
        articleCriteria.andPublishTimeLessThanOrEqualTo(currentTime);
        //截止时间大于当前时间
        articleCriteria.andUsefulTimeGreaterThanOrEqualTo(currentTime);
        //发布出去 ：是否发布：1 发布，2 ,未发布
        articleCriteria.andPublishEqualTo(1);
        articleCriteria.andAppNumberEqualTo(projectId);
        articleCriteria.andLangEqualTo(lang);
        //没有启用的不能进行启用
        List<ArticleColumn> articleColumnList = articleColumnService.selectArticleColumnNotOn();
        List<Long> articleColumnIds = new ArrayList<>();
        articleColumnList.forEach(articleColumn -> {
            articleColumnIds.add(articleColumn.getId());
        });
        if (CollectionUtils.isNotEmpty(articleColumnIds)) {
            articleCriteria.andColumnIdNotIn(articleColumnIds);
        }
        articleList = articleMapper.selectByExample(articleExample);
        //去除所有的articleColumnApp没有的开启的
        List<Article> articleTemp = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(articleList)) {
            //如果没有Appcolumn就删除
            for (Article article : articleList) {
                List<ArticleColumnApp> articleColumnAppList = articleColumnAppService.selectColumnAppNotOn(article.getLang(), article.getAppNumber(), article.getColumnId());
                if (articleColumnAppList.isEmpty()) {
                    articleTemp.add(article);
                }
            }
        }
        //增加到缓存中
        for (Article article : articleTemp) {
            HotArticleCachePo hotArticleCachePo = new HotArticleCachePo(article);
            List<ArticleTag> articleTagList = articleTagService.selectByArticleId(article.getId());
            List<String> tagList = new ArrayList<>();
            for (ArticleTag articleTag : articleTagList) {
                tagList.add(articleTag.getTagName());
            }
            hotArticleCachePo.setTags(tagList);
            hotArticleCachePoList.add(hotArticleCachePo);
        }

        logger.debug(lang+ projectId +"进行更新。。。。。。。。。。。。。。。。。");
        hotArticleCacheDao.updateAndInsertHotArticleCache(lang, projectId, hotArticleCachePoList);
        logger.debug(lang+ projectId +"更新完成。。。。。。。。。。。。。。。。。");
        return hotArticleCachePoList;
    }

    @Override
    public ArticleTotalityInfoVo updateArticleTotalityInfo(String lang, String projectId) {
        //选取所有的AppColumn必须要启动
        ArticleTotalityInfoVo articleTotalityInfoVo = new ArticleTotalityInfoVo();
        List<ArticleColumnApp> articleColumnApps = articleColumnAppService.selectAppArticleColumnAppAll(lang,projectId);
        //今日推荐
        List<ArticleDetailVo> articleDetailVos = selectTodayArticle(lang, projectId);
        //今日推荐id
        List<Long> articleIdList = new ArrayList<>();
        //今日推荐的三个id
        articleDetailVos.forEach(articleDetailVo -> {
            articleIdList.add(articleDetailVo.getArticleId());
        });
        articleTotalityInfoVo.setTodayRecommends(articleDetailVos);
        articleColumnApps.forEach(articleColumnApp -> {
            ArticleColumn articleColumn = articleColumnService.selectArticleColumnById(articleColumnApp.getArticleColumnId());
            if (articleColumn != null) {
                AppColumnKey appColumnKey = new AppColumnKey();
                appColumnKey.setImageUrl(articleColumn.getIconUrl());
                appColumnKey.setName(articleColumn.getKeyName());
                articleTotalityInfoVo.getKeys().add(appColumnKey);
                AppArticleColumnInfoVo appArticleColumnInfoVo = new AppArticleColumnInfoVo();
                appArticleColumnInfoVo.setColumnId(articleColumn.getId());
                appArticleColumnInfoVo.setColumnName(articleColumn.getName());
                appArticleColumnInfoVo.setKey(articleColumn.getKeyName());
                appArticleColumnInfoVo.setImageUrl(articleColumn.getIconUrl());
                //每一类文章最多发布2篇
                appArticleColumnInfoVo.setArticleList(selectByArticleColumnIdFirst(lang, projectId, articleColumnApp.getArticleColumnId(), 1, 2, articleIdList));
                articleTotalityInfoVo.getColumnList().add(appArticleColumnInfoVo);
            }
        });
        return articleTotalityInfoVo;
    }

    @Override
    public List<TodayArticleCachePo> updateTodayArticleCachePo(String lang, String projectId) {
        List<TodayArticleCachePo> todayArticleCachePoList = new ArrayList<>();
        List<Article> articleList;
        List<ArticleDetailVo> articleDetailVos = new ArrayList<>();
        ArticleExample articleExample = new ArticleExample();
        articleExample.setOrderByClause("publish_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        //发布时间小于当前时间
        articleCriteria.andPublishTimeLessThan(System.currentTimeMillis() / 1000);
        //截止时间大于当前时间
        articleCriteria.andUsefulTimeGreaterThan(System.currentTimeMillis() / 1000);
        //发布出去 ：是否发布：1 发布，2 ,未发布
        articleCriteria.andPublishEqualTo(1);
        articleCriteria.andAppNumberEqualTo(projectId);
        articleCriteria.andLangEqualTo(lang);
        //没有启用的不能进行启用Today
        List<ArticleColumn> articleColumnList = articleColumnService.selectArticleColumnNotOn();
        List<Long> articleColumnIds = new ArrayList<>();
        articleColumnList.forEach(articleColumn -> {
            articleColumnIds.add(articleColumn.getId());
        });
        if (CollectionUtils.isNotEmpty(articleColumnIds)) {
            articleCriteria.andColumnIdNotIn(articleColumnIds);
        }
        articleList = articleMapper.selectByExample(articleExample);
        //如果没有Appcolumn就删除
        //推送三个
        //app 栏目id
        List<Long> articleColumnId = new ArrayList<>();
        int i = 0;
        for (Article article : articleList) {
            List<String> articleTagNames = new ArrayList<>();
            List<ArticleColumnApp> articleColumnAppList = articleColumnAppService.selectColumnAppNotOn(article.getLang(), article.getAppNumber(), article.getColumnId());
            if (!articleColumnAppList.isEmpty()) {
                continue;
            }
            //如果存在article的栏目相同，就不要该文章，否则增加文章
            if (articleColumnId.contains(article.getColumnId())) {
                continue;
            }
            articleColumnId.add(article.getColumnId());
            articleTagService.selectByArticleId(article.getId()).forEach(articleTag -> articleTagNames.add(articleTag.getTagName()));
            ArticleDetailVo articleDetailVo = new ArticleDetailVo(article);
            articleDetailVo.setTags(articleTagNames);
            articleDetailVos.add(articleDetailVo);
            i++;
            if (i > 2) {
                break;
            }
        }
        for (ArticleDetailVo articleDetailVo : articleDetailVos) {
            todayArticleCachePoList.add(new TodayArticleCachePo(articleDetailVo));
        }
        //更新缓存
        todayArticleCacheDao.updateAndInsertTodayArticleCache(lang,projectId,todayArticleCachePoList);
        return todayArticleCachePoList;
    }

    @Override
    public int updateArticleMock(ArticleMockParam articleMockParam) {
        Article article = articleMapper.selectByPrimaryKey(Long.parseLong(articleMockParam.getArticleId()));
        if(article == null){
            return 2;//2代表没有此文章
        }
        if(articleMockParam.getMockBrowseNumber() != 0 || article.getMockBrowseNumber() == 0){
            article.setMockBrowseNumber(articleMockParam.getMockBrowseNumber());
        }
        if(articleMockParam.getMockCollectNumber() != 0 || article.getMockCollectNumber() == 0){
            article.setMockCollectNumber(articleMockParam.getMockCollectNumber());
        }
        if(articleMockParam.getMockPraiseNumber() != 0 || article.getMockPraiseNumber() == 0){
            article.setMockPraiseNumber(articleMockParam.getMockPraiseNumber());
        }
        article.setMockCollectNumber(articleMockParam.getMockCollectNumber());
        article.setMockPraiseNumber(articleMockParam.getMockPraiseNumber());
        return articleMapper.updateByPrimaryKeySelective(article);
    }

    @Override
    public List<ArticleVo> selectArticleList(String companyNumber, String appNumber, String lang, String columnId, String key, long order, int pageIndex, int pageSize) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        List<Article> articleList;
        ArticleExample articleExample = new ArticleExample();
        articleExample.setLimitStart((pageIndex - 1) * pageSize);
        articleExample.setLimitEnd(pageSize);
        articleExample.setOrderByClause("recommend_index asc,browse_number desc,publish_time desc");
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        if (StringUtils.isNotBlank(lang)) {
            articleCriteria.andLangEqualTo(lang);
        }
        if (StringUtils.isNotBlank(columnId)) {
            articleCriteria.andColumnIdEqualTo(Long.parseLong(columnId));
        }
        if (StringUtils.isNotBlank(appNumber)) {
            articleCriteria.andAppNumberEqualTo(appNumber);
        }
        if (StringUtils.isNotBlank(key)) {
            articleCriteria.andTitleLike("%" + key + "%");
        }
        if (companyNumber != null) {
            articleCriteria.andCompanyNumberEqualTo(companyNumber);
        }
        articleList = articleMapper.selectByExample(articleExample);
        articleList.forEach(article -> {
            ArticleVo articleVo = new ArticleVo(article);
            ArticleAppParam articleAppParam = new ArticleAppParam();
            articleAppParam.setAppName(article.getAppName());
            articleAppParam.setAppNumber(article.getAppNumber());
            articleAppParam.setColumnId(article.getColumnId().toString());
            articleAppParam.setColumnName(article.getColumnName());
            articleVo.getApp().add(articleAppParam);
            articleTagService.selectByArticleId(article.getId()).forEach(articleTag -> {
                ArticleTagParam articleTagParam = new ArticleTagParam(articleTag.getTagTypeId().toString(), articleTag.getTagTypeName(), articleTag.getTagId().toString(), articleTag.getTagName());
                articleVo.getTags().add(articleTagParam);
            });
            articleVoList.add(articleVo);
        });
        return articleVoList;
    }

    @Override
    public int countArticleList(String companyNumber, String appNumber, String lang, String columnId, String key, long order) {
        ArticleExample articleExample = new ArticleExample();
        ArticleExample.Criteria articleCriteria = articleExample.createCriteria();
        if (lang != null) {
            articleCriteria.andLangEqualTo(lang);
        }
        if (columnId != null) {
            articleCriteria.andColumnIdEqualTo(Long.parseLong(columnId));
        }
        if (appNumber != null) {
            articleCriteria.andAppNumberEqualTo(appNumber);
        }
        if (key != null) {
            articleCriteria.andTitleLike("%" + key + "%");
        }
        if (companyNumber != null) {
            articleCriteria.andCompanyNumberEqualTo(companyNumber);
        }
        return articleMapper.countByExample(articleExample);
    }


}
